<template><div><p>本文档最新版为 <a href="https://learnku.com/docs/laravel/10.x" target="_blank" rel="noopener noreferrer">10.x</a>，旧版本可能放弃维护，推荐阅读最新版！</p>
<h2 id="facades" tabindex="-1"><a class="header-anchor" href="#facades"><span>Facades</span></a></h2>
<ul>
<li><a href="#introduction">简介</a></li>
<li><a href="#when-to-use-facades">何时使用 Facades</a>
<ul>
<li><a href="#facades-vs-dependency-injection">Facades 相较于依赖注入</a></li>
<li><a href="#facades-vs-helper-functions">Facades 相较于辅助函数</a></li>
</ul>
</li>
<li><a href="#how-facades-work">Facades 工作原理</a></li>
<li><a href="#real-time-facades">实时 Facades</a></li>
<li><a href="#facade-class-reference">Facade 参考类</a></li>
</ul>
<h2 id="简介" tabindex="-1"><a class="header-anchor" href="#简介"><span>简介</span></a></h2>
<p>Facades 为应用的 <a href="https://learnku.com/docs/laravel/6.x/container" target="_blank" rel="noopener noreferrer">服务容器</a> 提供了一个「静态」 接口。Laravel 自带了很多 Facades，可以访问绝大部分功能。Laravel Facades 实际是服务容器中底层类的 「静态代理」 ，相对于传统静态方法，在使用时能够提供更加灵活、更加易于测试、更加优雅的语法。</p>
<p>所有的 Laravel Facades 都定义在 <code v-pre>Illuminate\Support\Facades</code> 命名空间下。所以，我们可以轻松的使用 Facade ：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Cache</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Route</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/cache'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>在 Laravel 文档中，有很多示例代码都会使用 Facades 来演示框架的各种功能。</p>
<h2 id="何时使用-facades" tabindex="-1"><a class="header-anchor" href="#何时使用-facades"><span>何时使用 Facades</span></a></h2>
<p>Facades 有很多优点，它提供了简单，易记的语法，从而无需手动注入或配置长长的类名。此外，由于他们对 PHP 静态方法的独特调用，使得测试起来非常容易。</p>
<p>然而，在使用 Facades 时，有些地方需要特别注意。使用 Facades 时最主要的危险就是会引起类作用范围的膨胀。由于 Facades 使用起来非常简单并且不需要注入，就会使得我们不经意间在单个类中使用许多 Facades ，从而导致类变得越来越大。然而使用依赖注入的时候，使用的类越多，构造方法就会越长，在视觉上注意到这个类有些庞大了。因此在使用 Facades 的时候，要特别注意控制类的大小，让类的作用范围保持短小。</p>
<blockquote>
<p>Tip：在开发与 Laravel 进行交互的第三方扩展包时，最好选择注入 <a href="https://learnku.com/docs/laravel/6.x/contracts" target="_blank" rel="noopener noreferrer">Laravel 契约</a> 而不使用 Facades 。因为扩展包是在 Laravel 之外构建，你无法使用 Laravel Facades 测试辅助函数</p>
</blockquote>
<h3 id="facades-相较于依赖注入" tabindex="-1"><a class="header-anchor" href="#facades-相较于依赖注入"><span>Facades 相较于依赖注入</span></a></h3>
<p>依赖注入的主要好处之一是能交换注入类的实现。在测试的时候非常有用，因为你可以注入一个 mock 或者 stub，并断言 stub 上的各种方法。</p>
<p>通常，真正的静态方法是不可能 mock 或 stub 的。但是 Facades 使用动态方法对服务容器中解析出来的对象方法的调用进行了代理，我们也可以像测试注入类实例一样测试 Facades。比如，像下面的路由:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Cache</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Route</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/cache'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>我们可以带上我们期望的参数编写下面的测试代码来验证 <code v-pre>Cache::get</code> 方法:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Cache</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * 一个基础功能的测试用例。</span>
<span class="line"> *</span>
<span class="line"> * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">void</span></span></span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">testBasicExample</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">shouldReceive</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'get'</span><span class="token punctuation">)</span></span>
<span class="line">         <span class="token operator">-></span><span class="token function">with</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">)</span></span>
<span class="line">         <span class="token operator">-></span><span class="token function">andReturn</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'value'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">visit</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/cache'</span><span class="token punctuation">)</span></span>
<span class="line">         <span class="token operator">-></span><span class="token function">see</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'value'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="facades-相较于辅助函数" tabindex="-1"><a class="header-anchor" href="#facades-相较于辅助函数"><span>Facades 相较于辅助函数</span></a></h3>
<p>除了 Facades，Laravel 还包含各种 『辅助函数』 来实现这些常用功能，比如生成视图、触发事件、任务调度或者发送 HTTP 响应。许多辅助函数都有与之对应的 Facades 。例如，下面这个 Facades 和辅助函数的作用是一样的:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">return</span> <span class="token class-name static-context">View</span><span class="token operator">::</span><span class="token function">make</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'profile'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">return</span> <span class="token function">view</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'profile'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Facade 和辅助函数之间没有实际的区别。当你使用辅助函数时，你可以像测试相应的 Facade 那样进行测试。例如，下面的路由:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Route</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/cache'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">return</span> <span class="token function">cache</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>在底层实现，辅助函数 <code v-pre>cache</code> 实际是调用 <code v-pre>Cache</code> 这个 Facade 的 <code v-pre>get</code> 方法。因此，尽管我们使用的是辅助函数，我们依然可以带上我们期望的参数编写下面的测试代码来验证该方法:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Cache</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * 一个基础功能的测试用例。</span>
<span class="line"> *</span>
<span class="line"> * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">void</span></span></span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">testBasicExample</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">shouldReceive</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'get'</span><span class="token punctuation">)</span></span>
<span class="line">         <span class="token operator">-></span><span class="token function">with</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'key'</span><span class="token punctuation">)</span></span>
<span class="line">         <span class="token operator">-></span><span class="token function">andReturn</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'value'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">visit</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/cache'</span><span class="token punctuation">)</span></span>
<span class="line">         <span class="token operator">-></span><span class="token function">see</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'value'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="facades-工作原理" tabindex="-1"><a class="header-anchor" href="#facades-工作原理"><span>Facades 工作原理</span></a></h2>
<p>在 Laravel 应用中，Facade 就是一个可以从容器访问对象的类。其中核心的部件就是 <code v-pre>Facade</code> 类。不管是 Laravel 自带的 Facades，还是自定义的 Facades，都继承自 <code v-pre>Illuminate\Support\Facades\Facade</code> 类。</p>
<p><code v-pre>Facade</code> 基类使用了<code v-pre>__callStatic()</code> 魔术方法，直到对象从容器中被解析出来后，才会进行调用。在下面的例子中，调用了 Laravel 的缓存系统。通过浏览这段代码，可以假定在 <code v-pre>Cache</code> 类中调用了静态方法 <code v-pre>get</code>：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Controllers</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Controllers<span class="token punctuation">\</span>Controller</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Cache</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">UserController</span> <span class="token keyword">extends</span> <span class="token class-name">Controller</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 显示给定用户的信息。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@param</span>  <span class="token class-name"><span class="token keyword">int</span></span>  <span class="token parameter">$id</span></span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name">Response</span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">showProfile</span><span class="token punctuation">(</span><span class="token variable">$id</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$user</span> <span class="token operator">=</span> <span class="token class-name static-context">Cache</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'user:'</span><span class="token operator">.</span><span class="token variable">$id</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token keyword">return</span> <span class="token function">view</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'profile'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'user'</span> <span class="token operator">=></span> <span class="token variable">$user</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>注意在上面这段代码中，我们『导入』了 <code v-pre>Cache</code> Facade。这个 Facade 作为访问 <code v-pre>Illuminate\Contracts\Cache\Factory</code> 接口底层实现的代理。我们使用 Facade 进行的任何调用都将传递给 Laravel 缓存服务的底层实例。</p>
<p>如果我们看一下 <code v-pre>Illuminate\Support\Facades\Cache</code> 这个类，你会发现类中根本没有 <code v-pre>get</code> 这个静态方法：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">Cache</span> <span class="token keyword">extends</span> <span class="token class-name">Facade</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 获取组件的注册名称。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">string</span></span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">protected</span> <span class="token keyword">static</span> <span class="token keyword">function</span> <span class="token function-definition function">getFacadeAccessor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token string single-quoted-string">'cache'</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><code v-pre>Cache</code> Facade 继承了 Facade 类，并且定义了 <code v-pre>getFacadeAccessor()</code> 方法。这个方法的作用是返回服务容器绑定的名称。当用户调用 <code v-pre>Cache</code> Facade 中的任何静态方法时，Laravel 会从 <a href="https://learnku.com/docs/laravel/6.x/container" target="_blank" rel="noopener noreferrer">服务容器</a> 中解析 <code v-pre>cache</code> 绑定以及该对象运行所请求的方法（在这个例子中就是 <code v-pre>get</code> 方法）。</p>
<h2 id="实时-facades" tabindex="-1"><a class="header-anchor" href="#实时-facades"><span>实时 Facades</span></a></h2>
<p>使用实时 Facades，你可以将应用程序中的任何类视为 Facade。为了说明这是如何使用的，我们来看看另一种方法。例如，假设我们的 <code v-pre>Podcast</code> 模型有一个 <code v-pre>publish</code> 方法。然而，为了发布 Podcast，我们需要注入一个 <code v-pre>Publisher</code> 实例：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Contracts<span class="token punctuation">\</span>Publisher</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Model</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">Podcast</span> <span class="token keyword">extends</span> <span class="token class-name">Model</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 发布 Podcast。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@param</span>  <span class="token class-name">Publisher</span>  <span class="token parameter">$publisher</span></span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">void</span></span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">publish</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Publisher</span> <span class="token variable">$publisher</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">update</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'publishing'</span> <span class="token operator">=></span> <span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token variable">$publisher</span><span class="token operator">-></span><span class="token function">publish</span><span class="token punctuation">(</span><span class="token variable">$this</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>将发布者的实现注入到该方法中，我们可以轻松地测试这种方法，因为我们可以模拟注入的发布者。但是，它要求我们每次调用 <code v-pre>publish</code> 方法时都要传递一个发布者实例。使用实时的 Facades，我们可以保持同样的可测试性，而不需要显式地通过 <code v-pre>Publisher</code> 实例。要生成实时 <code v-pre>Facade</code>，请在导入类的名称空间中加上 Facades：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Facades<span class="token punctuation">\</span>App<span class="token punctuation">\</span>Contracts<span class="token punctuation">\</span>Publisher</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Model</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">Podcast</span> <span class="token keyword">extends</span> <span class="token class-name">Model</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 发布 Podcast。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">void</span></span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">publish</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">update</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'publishing'</span> <span class="token operator">=></span> <span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token class-name static-context">Publisher</span><span class="token operator">::</span><span class="token function">publish</span><span class="token punctuation">(</span><span class="token variable">$this</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>当使用实时 Facade 时，发布者实现将通过使用 <code v-pre>Facades</code> 前缀后出现的接口或类名的部分来解决服务容器的问题。在测试时，我们可以使用 Laravel 的内置 facade 测试辅助函数来模拟这种方法调用：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">Tests<span class="token punctuation">\</span>Feature</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Podcast</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Tests<span class="token punctuation">\</span>TestCase</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Facades<span class="token punctuation">\</span>App<span class="token punctuation">\</span>Contracts<span class="token punctuation">\</span>Publisher</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Foundation<span class="token punctuation">\</span>Testing<span class="token punctuation">\</span>RefreshDatabase</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">PodcastTest</span> <span class="token keyword">extends</span> <span class="token class-name">TestCase</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">use</span> <span class="token package">RefreshDatabase</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 一个测试演示。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">void</span></span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">test_podcast_can_be_published</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$podcast</span> <span class="token operator">=</span> <span class="token function">factory</span><span class="token punctuation">(</span><span class="token class-name static-context">Podcast</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token class-name static-context">Publisher</span><span class="token operator">::</span><span class="token function">shouldReceive</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'publish'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">once</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">with</span><span class="token punctuation">(</span><span class="token variable">$podcast</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token variable">$podcast</span><span class="token operator">-></span><span class="token function">publish</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="facade-类参考" tabindex="-1"><a class="header-anchor" href="#facade-类参考"><span>Facade 类参考</span></a></h2>
<p>在下面你可以找到每个 Facade 类及其对应的底层类。这是一个查找给定 Facade 类 API 文档的工具。<a href="https://learnku.com/docs/laravel/6.x/container" target="_blank" rel="noopener noreferrer">服务容器绑定</a> 的关键信息也包含在内。</p>
<table>
<thead>
<tr>
<th>Facade</th>
<th>Class</th>
<th>服务容器绑定</th>
</tr>
</thead>
<tbody>
<tr>
<td>App</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Foundation/Application.html" target="_blank" rel="noopener noreferrer">Illuminate\Foundation\Application</a></td>
<td><code v-pre>app</code></td>
</tr>
<tr>
<td>Artisan</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Contracts/Console/Kernel.html" target="_blank" rel="noopener noreferrer">Illuminate\Contracts\Console\Kernel</a></td>
<td><code v-pre>artisan</code></td>
</tr>
<tr>
<td>Auth</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Auth/AuthManager.html" target="_blank" rel="noopener noreferrer">Illuminate\Auth\AuthManager</a></td>
<td><code v-pre>auth</code></td>
</tr>
<tr>
<td>Auth (Instance)</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Contracts/Auth/Guard.html" target="_blank" rel="noopener noreferrer">Illuminate\Contracts\Auth\Guard</a></td>
<td><code v-pre>auth.driver</code></td>
</tr>
<tr>
<td>Blade</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/View/Compilers/BladeCompiler.html" target="_blank" rel="noopener noreferrer">Illuminate\View\Compilers\BladeCompiler</a></td>
<td><code v-pre>blade.compiler</code></td>
</tr>
<tr>
<td>Broadcast</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Contracts/Broadcasting/Factory.html" target="_blank" rel="noopener noreferrer">Illuminate\Contracts\Broadcasting\Factory</a></td>
<td></td>
</tr>
<tr>
<td>Broadcast (Instance)</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Contracts/Broadcasting/Broadcaster.html" target="_blank" rel="noopener noreferrer">Illuminate\Contracts\Broadcasting\Broadcas...</a></td>
<td></td>
</tr>
<tr>
<td>Bus</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Contracts/Bus/Dispatcher.html" target="_blank" rel="noopener noreferrer">Illuminate\Contracts\Bus\Dispatcher</a></td>
<td></td>
</tr>
<tr>
<td>Cache</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Cache/CacheManager.html" target="_blank" rel="noopener noreferrer">Illuminate\Cache\CacheManager</a></td>
<td><code v-pre>cache</code></td>
</tr>
<tr>
<td>Cache (Instance)</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Cache/Repository.html" target="_blank" rel="noopener noreferrer">Illuminate\Cache\Repository</a></td>
<td><code v-pre>cache.store</code></td>
</tr>
<tr>
<td>Config</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Config/Repository.html" target="_blank" rel="noopener noreferrer">Illuminate\Config\Repository</a></td>
<td><code v-pre>config</code></td>
</tr>
<tr>
<td>Cookie</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Cookie/CookieJar.html" target="_blank" rel="noopener noreferrer">Illuminate\Cookie\CookieJar</a></td>
<td><code v-pre>cookie</code></td>
</tr>
<tr>
<td>Crypt</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Encryption/Encrypter.html" target="_blank" rel="noopener noreferrer">Illuminate\Encryption\Encrypter</a></td>
<td><code v-pre>encrypter</code></td>
</tr>
<tr>
<td>DB</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Database/DatabaseManager.html" target="_blank" rel="noopener noreferrer">Illuminate\Database\DatabaseManager</a></td>
<td><code v-pre>db</code></td>
</tr>
<tr>
<td>DB (Instance)</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Database/Connection.html" target="_blank" rel="noopener noreferrer">Illuminate\Database\Connection</a></td>
<td><code v-pre>db.connection</code></td>
</tr>
<tr>
<td>Event</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Events/Dispatcher.html" target="_blank" rel="noopener noreferrer">Illuminate\Events\Dispatcher</a></td>
<td><code v-pre>events</code></td>
</tr>
<tr>
<td>File</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Filesystem/Filesystem.html" target="_blank" rel="noopener noreferrer">Illuminate\Filesystem\Filesystem</a></td>
<td><code v-pre>files</code></td>
</tr>
<tr>
<td>Gate</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Contracts/Auth/Access/Gate.html" target="_blank" rel="noopener noreferrer">Illuminate\Contracts\Auth\Access\Gate</a></td>
<td></td>
</tr>
<tr>
<td>Hash</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Contracts/Hashing/Hasher.html" target="_blank" rel="noopener noreferrer">Illuminate\Contracts\Hashing\Hasher</a></td>
<td><code v-pre>hash</code></td>
</tr>
<tr>
<td>Lang</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Translation/Translator.html" target="_blank" rel="noopener noreferrer">Illuminate\Translation\Translator</a></td>
<td><code v-pre>translator</code></td>
</tr>
<tr>
<td>Log</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Log/LogManager.html" target="_blank" rel="noopener noreferrer">Illuminate\Log\LogManager</a></td>
<td><code v-pre>log</code></td>
</tr>
<tr>
<td>Mail</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Mail/Mailer.html" target="_blank" rel="noopener noreferrer">Illuminate\Mail\Mailer</a></td>
<td><code v-pre>mailer</code></td>
</tr>
<tr>
<td>Notification</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Notifications/ChannelManager.html" target="_blank" rel="noopener noreferrer">Illuminate\Notifications\ChannelManager</a></td>
<td></td>
</tr>
<tr>
<td>Password</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Auth/Passwords/PasswordBrokerManager.html" target="_blank" rel="noopener noreferrer">Illuminate\Auth\Passwords\PasswordBrokerMa...</a></td>
<td><code v-pre>auth.password</code></td>
</tr>
<tr>
<td>Password (Instance)</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Auth/Passwords/PasswordBroker.html" target="_blank" rel="noopener noreferrer">Illuminate\Auth\Passwords\PasswordBroker</a></td>
<td><code v-pre>auth.password.broker</code></td>
</tr>
<tr>
<td>Queue</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Queue/QueueManager.html" target="_blank" rel="noopener noreferrer">Illuminate\Queue\QueueManager</a></td>
<td><code v-pre>queue</code></td>
</tr>
<tr>
<td>Queue (Instance)</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Contracts/Queue/Queue.html" target="_blank" rel="noopener noreferrer">Illuminate\Contracts\Queue\Queue</a></td>
<td><code v-pre>queue.connection</code></td>
</tr>
<tr>
<td>Queue (Base Class)</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Queue/Queue.html" target="_blank" rel="noopener noreferrer">Illuminate\Queue\Queue</a></td>
<td></td>
</tr>
<tr>
<td>Redirect</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Routing/Redirector.html" target="_blank" rel="noopener noreferrer">Illuminate\Routing\Redirector</a></td>
<td><code v-pre>redirect</code></td>
</tr>
<tr>
<td>Redis</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Redis/RedisManager.html" target="_blank" rel="noopener noreferrer">Illuminate\Redis\RedisManager</a></td>
<td><code v-pre>redis</code></td>
</tr>
<tr>
<td>Redis (Instance)</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Redis/Connections/Connection.html" target="_blank" rel="noopener noreferrer">Illuminate\Redis\Connections\Connection</a></td>
<td><code v-pre>redis.connection</code></td>
</tr>
<tr>
<td>Request</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Http/Request.html" target="_blank" rel="noopener noreferrer">Illuminate\Http\Request</a></td>
<td><code v-pre>request</code></td>
</tr>
<tr>
<td>Response</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Contracts/Routing/ResponseFactory.html" target="_blank" rel="noopener noreferrer">Illuminate\Contracts\Routing\ResponseFacto...</a></td>
<td></td>
</tr>
<tr>
<td>Response (Instance)</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Http/Response.html" target="_blank" rel="noopener noreferrer">Illuminate\Http\Response</a></td>
<td></td>
</tr>
<tr>
<td>Route</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Routing/Router.html" target="_blank" rel="noopener noreferrer">Illuminate\Routing\Router</a></td>
<td><code v-pre>router</code></td>
</tr>
<tr>
<td>Schema</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Database/Schema/Builder.html" target="_blank" rel="noopener noreferrer">Illuminate\Database\Schema\Builder</a></td>
<td></td>
</tr>
<tr>
<td>Session</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Session/SessionManager.html" target="_blank" rel="noopener noreferrer">Illuminate\Session\SessionManager</a></td>
<td><code v-pre>session</code></td>
</tr>
<tr>
<td>Session (Instance)</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Session/Store.html" target="_blank" rel="noopener noreferrer">Illuminate\Session\Store</a></td>
<td><code v-pre>session.store</code></td>
</tr>
<tr>
<td>Storage</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Filesystem/FilesystemManager.html" target="_blank" rel="noopener noreferrer">Illuminate\Filesystem\FilesystemManager</a></td>
<td><code v-pre>filesystem</code></td>
</tr>
<tr>
<td>Storage (Instance)</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Contracts/Filesystem/Filesystem.html" target="_blank" rel="noopener noreferrer">Illuminate\Contracts\Filesystem\Filesystem</a></td>
<td><code v-pre>filesystem.disk</code></td>
</tr>
<tr>
<td>URL</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Routing/UrlGenerator.html" target="_blank" rel="noopener noreferrer">Illuminate\Routing\UrlGenerator</a></td>
<td><code v-pre>url</code></td>
</tr>
<tr>
<td>Validator</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Validation/Factory.html" target="_blank" rel="noopener noreferrer">Illuminate\Validation\Factory</a></td>
<td><code v-pre>validator</code></td>
</tr>
<tr>
<td>Validator (Instance)</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/Validation/Validator.html" target="_blank" rel="noopener noreferrer">Illuminate\Validation\Validator</a></td>
<td></td>
</tr>
<tr>
<td>View</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/View/Factory.html" target="_blank" rel="noopener noreferrer">Illuminate\View\Factory</a></td>
<td><code v-pre>view</code></td>
</tr>
<tr>
<td>View (Instance)</td>
<td><a href="https://laravel.com/api/6.x/Illuminate/View/View.html" target="_blank" rel="noopener noreferrer">Illuminate\View\View</a></td>
<td></td>
</tr>
</tbody>
</table>
<blockquote>
<p>本译文仅用于学习和交流目的，转载请务必注明文章译者、出处、和本文链接<br>
我们的翻译工作遵照 <a href="https://learnku.com/docs/guide/cc4.0/6589" target="_blank" rel="noopener noreferrer">CC 协议</a>，如果我们的工作有侵犯到您的权益，请及时联系我们。</p>
</blockquote>
<hr>
<blockquote>
<p>原文地址：<a href="https://learnku.com/docs/laravel/6.x/facades/5133" target="_blank" rel="noopener noreferrer">https://learnku.com/docs/laravel/6.x/fac...</a></p>
<p>译文地址：<a href="https://learnku.com/docs/laravel/6.x/facades/5133" target="_blank" rel="noopener noreferrer">https://learnku.com/docs/laravel/6.x/fac...</a></p>
</blockquote>
</div></template>


